package main

import (
	"gitee.com/daichang01/my-basic-go/webook/internal/repository"
	"gitee.com/daichang01/my-basic-go/webook/internal/repository/dao"
	"gitee.com/daichang01/my-basic-go/webook/internal/service"
	"gitee.com/daichang01/my-basic-go/webook/internal/web"
	"gitee.com/daichang01/my-basic-go/webook/internal/web/middleware"
	"github.com/gin-contrib/cors"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/redis"
	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"strings"
	"time"
)

func main() {
	db := initDB()
	server := initWebServer()
	u := initUser(db)
	u.RegisterRoutesV1(server.Group("/users")) //看自己想不想用分组注册，品味问题
	//u.RegisterRoutes(server)
	server.Run(":8080")
}

func initWebServer() *gin.Engine {
	server := gin.Default()
	//使用将全局中间件附加到路由器。即通过 Use() 附加的中间件将包含在每个请求的处理程序链中。甚至 404、405、静态文件……例如，
	//这是记录器或错误管理中间件的正确位置。
	//func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes
	server.Use(cors.New(cors.Config{
		//AllowOrigins:  []string{"http://localhost:3000"},
		//AllowMethods:  []string{"POST", "GET"},
		AllowHeaders:  []string{"content-type", "authorization"},
		ExposeHeaders: []string{"Content-Length"},
		//是否允许带cookie之类的东西
		AllowCredentials: true,
		AllowOriginFunc: func(origin string) bool {
			//return origin == "https://github.com"
			if strings.HasPrefix(origin, "http://localhost") {
				//开发环境
				return true
			}
			return strings.Contains(origin, "dchouse.com")
		},
		MaxAge: 12 * time.Hour,
	}))
	//创建了一个新的会话存储，该存储使用 Cookie 来保存会话数据。这里传递的参数 []byte("secret") 是用于加密和解密会话数据的密钥。
	//store := cookie.NewStore([]byte("secret"))
	//基于内存
	//store := memstore.NewStore([]byte("vTijcpMW2LILLWEXXm92qKvvDZjsV8yt"), []byte("GFMkOcGGUx5xMx61IyfTXDRqIYIooTO8"))
	store, err := redis.NewStore(16,
		"tcp", "localhost:6379", "", []byte("vTijcpMW2LILLWEXXm92qKvvDZjsV8yt"), []byte("GFMkOcGGUx5xMx61IyfTXDRqIYIooTO8"))
	if err != nil {
		panic(err)
	}
	server.Use(sessions.Sessions("mysession", store))

	server.Use(middleware.NewLoginMiddlewareBuilder().Build())

	return server
}

func initUser(db *gorm.DB) *web.UserHandler {
	ud := dao.NewUserDAO(db)
	repo := repository.NewUserRepository(ud)
	svc := service.NewUserService(repo)
	u := web.NewUserHandler(svc)
	return u
}

func initDB() *gorm.DB {
	db, err := gorm.Open(mysql.Open("root:root@tcp(localhost:13316)/webook"))
	if err != nil {
		//唯一需要初始化过程用panic
		//panic相当于整个goroutine结束
		//一旦初始化出错，应用不要启动
		panic(err)
	}
	err = dao.InitTable(db)
	if err != nil {
		panic(err)
	}
	return db
}
